#include "ViewManager.h"
#include "IView.h"
#include "ViewContent.h"
#include "MenuView.h"
#include "GameView.h"

using namespace Views;

ViewManager::ViewManager(const std::string &resource_dir, const std::string &title, const glm::ivec2 &viewport, unsigned int alignment)
	: resource_dir(resource_dir)
{
	TCODConsole::setCustomFont((resource_dir + "fonts/" + "terminal.png").c_str(), TCOD_FONT_LAYOUT_ASCII_INCOL, 16,16);
	TCODConsole::initRoot(viewport.x, viewport.y, title.c_str(), true, TCOD_RENDERER_GLSL);
	TCODConsole::setCustomFont((resource_dir + "fonts/" + "terminal.png").c_str(), TCOD_FONT_LAYOUT_ASCII_INCOL, 16,16);
	TCODConsole::root->setAlignment((TCOD_alignment_t)alignment);
	TCODConsole::root->clear();
}

ViewManager::~ViewManager()
{
	while(!active_view.empty())
		active_view.pop();
	while(!active_gui_view.empty())
		active_gui_view.pop();
}

void ViewManager::update(float dt)
{
	if(!active_view.empty())
		active_view.top()->update(dt);
	if(!active_gui_view.empty())
		active_gui_view.top()->update(dt);
}

void ViewManager::render()
{
	if(!active_view.empty())
		active_view.top()->render();
	if(!active_gui_view.empty())
		active_gui_view.top()->render();
}

void ViewManager::add(const std::string &view_file)
{
	ViewContent content(resource_dir + "Views/" + view_file);
	IView *view;
	switch(content.getType())
	{
	case VIEW_MENU:
		view = new MenuView(content, TCODConsole::root);
		break;
	case VIEW_GAME:
		view = new GameView(content, TCODConsole::root);
		break;
	case VIEW_TYPE_COUNT:
	case VIEW_UNKNOWN:
	default:
		std::cout << "Failed to add view " << view_file << std::endl;
		return;
	};

	views.push_back(std::unique_ptr<IView>(view));
}

void ViewManager::pushActive(Totem::HashedString1 view_id)
{
	for(unsigned int i = 0; i < views.size(); i++)
	{
		if(views[i]->getId() == view_id.getStr())
		{
			active_view.push(views[i].get());
			break;
		}
	}
}

void ViewManager::pushActiveGui(Totem::HashedString1 view_id)
{
	for(unsigned int i = 0; i < views.size(); i++)
	{
		if(views[i]->getId() == view_id.getStr())
		{
			active_gui_view.push(views[i].get());
			break;
		}
	}
}

void ViewManager::popActive()
{
	if(!active_view.empty())
		active_view.pop();
}

void ViewManager::popActiveGui()
{
	if(!active_gui_view.empty())
		active_gui_view.pop();
}

void ViewManager::inputKeyDown(TCOD_key_t &key, TCOD_mouse_t &mouse)
{
	bool used = false;
	if(!active_gui_view.empty())
		used = active_gui_view.top()->inputKeyDown(key,mouse);

	if(!used && !active_view.empty())
		active_view.top()->inputKeyDown(key,mouse);
}

void ViewManager::inputKeyUp(TCOD_key_t &key, TCOD_mouse_t &mouse)
{
	bool used = false;
	if(!active_gui_view.empty())
		used = active_gui_view.top()->inputKeyUp(key,mouse);

	if(!used && !active_view.empty())
		active_view.top()->inputKeyUp(key,mouse);
}

void ViewManager::motion(TCOD_key_t &key, TCOD_mouse_t &mouse)
{
	bool used = false;
	if(!active_gui_view.empty())
		used = active_gui_view.top()->motion(key,mouse);

	if(!used && !active_view.empty())
		active_view.top()->motion(key,mouse);
}

void ViewManager::mousePressed(TCOD_key_t &key, TCOD_mouse_t &mouse)
{
	bool used = false;
	if(!active_gui_view.empty())
		used = active_gui_view.top()->mousePressed(key,mouse);

	if(!used && !active_view.empty())
		active_view.top()->mousePressed(key,mouse);
}

void ViewManager::mouseReleased(TCOD_key_t &key, TCOD_mouse_t &mouse)
{
	bool used = false;
	if(!active_gui_view.empty())
		used = active_gui_view.top()->mouseReleased(key,mouse);

	if(!used && !active_view.empty())
		active_view.top()->mouseReleased(key,mouse);
}
